package com.blockchain.securewallet;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;

import com.blockchain.securewallet.activities.LockActivity;
import com.blockchain.securewallet.activities.UnLockWalletActivity;
import com.blockchain.securewallet.model.db.Account;
import com.blockchain.securewallet.model.db.CoinWallet;
import com.blockchain.securewallet.model.db.dao.DaoMaster;
import com.blockchain.securewallet.model.db.dao.DaoSession;
import com.blockchain.securewallet.model.db.oper.AccountDaoOpe;
import com.blockchain.securewallet.utils.Constants;
import com.blockchain.securewallet.utils.Logger;
import com.blockchain.securewallet.utils.ToastUtils;
import com.google.common.base.Stopwatch;

import org.bitcoinj.crypto.MnemonicCode;
import org.bitcoinj.utils.Threading;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class WalletApp extends Application {
    private static final String TAG = "Wallet.App";

    public static final String BIP39_WORDLIST_ENGLISH = "bip39_english.txt";
    public static final String BIP39_WORDLIST_NUMBER = "bip39_number.txt";
    public static final String BIP39_WORDLIST_CHINESE_SIMPLIFIED = "bip39_chinese_simplified.txt";

    private static WalletApp sInstance = null;

    private List<CoinWallet> wallets = new ArrayList<>();

    private DaoSession daoSession;

    public static final long DEFAULT_FEE_BITCOIN = 50L; //每字节50聪
    public static final String KEY_BITCOIN_FEE_PER_BYTE = "key_fee_per_byte";
    public static final String KEY_LTC_FEE_PER_BYTE = "key_fee_per_byte_ltc";
    public static final String KEY_BCH_FEE_PER_BYTE = "key_fee_per_byte_bch";
    //用户设置的btc手续费
    public static final String KEY_BITCOIN_FEE_PER_BYTE_USER = "key_fee_per_byte_user";
    public static final String KEY_LTC_FEE_PER_BYTE_USER = "key_fee_per_byte_ltc_user";
    public static final String KEY_BCH_FEE_PER_BYTE_USER = "key_fee_per_byte_bch_user";

    public static final long DEFAULT_GAS_PRICE = 30L;//Gwei
    public static final long DEFAULT_GAS_LIMIT = 200000L;//Gas Limit
    public static final long DEFAULT_GAS_NONCE = 0L;//Gas Nonce

    public static final String KEY_NONCE = "key_nonce";
    public static final String KEY_NONCE_CUSTOM = "key_nonce_custom";
    public static final String KEY_GAS_PRICE = "key_gas_price";
    public static final String KEY_GAS_LIMIT = "key_gas_limit";
    //用户设置的eth KEY_GAS_PRICE
    public static final String KEY_GAS_PRICE_USER = "key_gas_price_user";
    //用户设置的eth KEY_GAS_LIMIT
    public static final String KEY_GAS_LIMIT_USER = "key_gas_limit_user";

    public static final String KEY_ID = "key_id";
    public static final String KEY_PAY_PASSWORD = "key_pay_password";

    public static final String KEY_WORDS_LIST = "key_words_list";

    public static final String KEY_LOCK_SET = "key_lock_set";
    public static final String KEY_LOCK_PASSWORD = "key_lock_password";

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public void setDaoSession(DaoSession daoSession) {
        this.daoSession = daoSession;
    }

    public static WalletApp getInstance() {
        return sInstance;
    }

    public static String uuid = "";

    public void initMnemonicCode(String name) {
        try {
            final Stopwatch watch = Stopwatch.createStarted();
            MnemonicCode.INSTANCE = new MnemonicCode(getAssets().open(name), null);
//            NumberMnemonicCode.INSTANCE = new NumberMnemonicCode(null);
            watch.stop();
            Log.i(TAG, "BIP39 wordlist loaded from: " + name + " took  " + watch);
        } catch (final IOException x) {
            throw new Error(x);
        }
    }

    @Override
    public void onCreate() {
        sInstance = this;

        //test

//        try {
//            LTCHDWallet ltchdWallet=LTCHDWallet.createWallet("oblige frog donor advice gold noodle muffin always rabbit little mushroom enroll","11111");
//            Log.i("testtest",ltchdWallet.address);
//        } catch (UnreadableWalletException e) {
//            e.printStackTrace();
//        }

        ToastUtils.init(this);



        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().permitDiskReads()
                .permitDiskWrites().penaltyLog().build());
        
        try {
             Threading.throwOnLockCycles(); 
        } catch (Exception e) {
            //e.printStackTrace();
            Logger.ds("error...");
        }

        org.bitcoinj.core.Context.enableStrictMode();
        org.bitcoinj.core.Context.propagate(Constants.CONTEXT);
        super.onCreate();
//        initMnemonicCode(BIP39_WORDLIST_ENGLISH);
        initMnemonicCode(BIP39_WORDLIST_NUMBER);
        initGreenDao();
        registerScreenActionReceiver();

        //重启应用为uuid赋值
//        SharedPreferences sf = WalletApp.getInstance().getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
//        uuid = sf.getString(WalletApp.KEY_ID,"");
    }

    private void initGreenDao() {
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "secure-wallet.db");
        DaoMaster master = new DaoMaster(helper.getWritableDb());
        daoSession = master.newSession();
    }

    public void saveGasPrice(long price) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_GAS_PRICE, price);
        editor.commit();
    }

    public void saveUserGasPrice(long price) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_GAS_PRICE_USER, price);
        editor.commit();
    }

    public void saveGasLimit(long limit) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_GAS_LIMIT, limit);
        editor.commit();
    }

    public void saveUserGasLimit(long limit) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_GAS_LIMIT_USER, limit);
        editor.commit();
    }

    public void saveNonce(long nonce) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_NONCE, nonce);
        editor.commit();
    }

    public void saveUserNonce(long nonce) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_NONCE_CUSTOM, nonce);
        editor.commit();
    }

    public long getGasPrice() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_GAS_PRICE, DEFAULT_GAS_PRICE);
    }

    //用户自定义的以太坊的手续费ETH  //单位为Gwei
    public long getUserGasPrice() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_GAS_PRICE_USER, DEFAULT_GAS_PRICE);
    }

    public long getGasLimit() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_GAS_LIMIT, DEFAULT_GAS_LIMIT);
    }

    public long getUserGasLimit() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_GAS_LIMIT_USER, DEFAULT_GAS_LIMIT);
    }

    public long getNonce() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_NONCE, DEFAULT_GAS_NONCE);
    }

    public long getUserNonce() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getLong(KEY_NONCE_CUSTOM, DEFAULT_GAS_NONCE);
    }

    public void saveBitCoinFee(long value) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_BITCOIN_FEE_PER_BYTE, value);
        editor.commit();
    }

    public void saveLtcCoinFee(long value) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_LTC_FEE_PER_BYTE, value);
        editor.commit();
    }


    public void saveBchCoinFee(long value) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_BCH_FEE_PER_BYTE, value);
        editor.commit();
    }

    //BTC/KB  注意/KB，这里没有除以1000
    public void saveUserLtcFee(long value) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_LTC_FEE_PER_BYTE_USER, value);
        editor.commit();
    }



    //BTC/KB  注意/KB，这里没有除以1000
    public void saveUserBitCoinFee(long value) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putLong(KEY_BITCOIN_FEE_PER_BYTE_USER, value);
        editor.commit();
    }


    public void saveWordsList(String words) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putString(KEY_WORDS_LIST, words);
        editor.commit();
    }

    //最佳手续费(一开始有个默认值，可随着热钱包同步更新过来)
    public long getBitCoinFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //单位 聪\KB
        return sf.getLong(KEY_BITCOIN_FEE_PER_BYTE, 50L);
    }

    //最佳手续费(一开始有个默认值，可随着热钱包同步更新过来)
    public long getLtcCoinFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //单位 聪\KB
        return sf.getLong(KEY_LTC_FEE_PER_BYTE, 50L);
    }

    //最佳手续费(一开始有个默认值，可随着热钱包同步更新过来)
    public long getBchCoinFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //单位 聪\KB
        return sf.getLong(KEY_BCH_FEE_PER_BYTE, 10000L);
    }



    //自定义手续费(用户自己填的值)   
    public long getUserBitCoinFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //注意这里的单位是 聪  而不是 聪\KB
        return sf.getLong(KEY_BITCOIN_FEE_PER_BYTE_USER, 50L);
    }

    //自定义手续费(用户自己填的值)
    public long getUserLtcFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //注意这里的单位是 聪  而不是 聪\KB
        return sf.getLong(KEY_LTC_FEE_PER_BYTE_USER, 100000L);
    }

    //自定义手续费(用户自己填的值)
    public long getUserBchFee() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        //注意这里的单位是 聪  而不是 聪\KB
        return sf.getLong(KEY_BCH_FEE_PER_BYTE_USER, 10000L);
    }


    public String getWordsList() {
        return queryCurrrentAccount().getMemorizing_words();
//        SharedPreferences sf = getSharedPreferences(getPackageName(),Context.MODE_PRIVATE);
//        return sf.getString(KEY_WORDS_LIST,"");
    }

    public void saveLockPasswordSet(Boolean b) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putBoolean(KEY_LOCK_SET, b);
        editor.commit();
    }

    public boolean isLockPasswordSet() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getBoolean(KEY_LOCK_SET, false);
    }

    public void saveLockPassword(String password) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putString(KEY_LOCK_PASSWORD, password);
        editor.commit();
    }

    public String getLockPassword() {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        return sf.getString(KEY_LOCK_PASSWORD, "");
    }

    public void savePayPassword(String password) {
        SharedPreferences sf = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sf.edit();
        editor.putString(KEY_PAY_PASSWORD, password);
        editor.commit();
    }

    public String getPayPassword() {
        return queryCurrrentAccount() == null ? null : queryCurrrentAccount().getPayPassword();
    }

    /**
     * 实现广播接收者
     */
    private final BroadcastReceiver ScreenActionReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, final Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_ON)) {

//                Log.i("screenscreen","ACTION_SCREEN_ON"+uuid);
//                if (!uuid.equals("")) {//设置了手势密码就输入手势密码，没有的话默认是支付密码
//                    if (isLockPasswordSet() && !TextUtils.isEmpty(getLockPassword())) {
//                        Log.i("screenscreen","isLockPasswordSet");
//                        Intent lockIntent = new Intent();
//                        lockIntent.setClass(getApplicationContext(), LockActivity.class);
//                        lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                        getApplicationContext().startActivity(lockIntent);
//                    } else {
//                        Log.i("screenscreen","noisLockPasswordSet");
//                        Intent i = new Intent();
//                        i.setClass(getApplicationContext(), UnLockWalletActivity.class);
//                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                        getApplicationContext().startActivity(i);
//                    }
//                }
            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                Log.i("screenscreen", "ACTION_SCREEN_OFF");

                if (getPayPassword() != null) {//设置了手势密码就输入手势密码，没有的话默认是支付密码
                    if (isLockPasswordSet() && !TextUtils.isEmpty(getLockPassword())) {
                        Log.i("screenscreen", "isLockPasswordSet");
                        Intent lockIntent = new Intent();
                        lockIntent.setClass(getApplicationContext(), LockActivity.class);
                        lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        getApplicationContext().startActivity(lockIntent);
                    } else {
                        Log.i("screenscreen", "noisLockPasswordSet");
                        Intent i = new Intent();
                        i.setClass(getApplicationContext(), UnLockWalletActivity.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        getApplicationContext().startActivity(i);
                    }
                }


            }


        }
    };

    // 该变量用于判断广播接受者是否已注册
    private boolean isRegisterReceiver = false;

    /**
     * 注册广播接收者
     */
    public void registerScreenActionReceiver() {
        if (!isRegisterReceiver) {
            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_SCREEN_ON);
            registerReceiver(ScreenActionReceiver, filter);
            isRegisterReceiver = true;
        }
    }

    /**
     * 取消注册广播接收者
     */
    public void unregisterScreenActionReceiver(Context context) {
        if (isRegisterReceiver) {
            isRegisterReceiver = false;
            context.unregisterReceiver(ScreenActionReceiver);
        }
    }

    public static List<CoinWallet> queryCurrrentWallet() {
        List<Account> accountList=AccountDaoOpe.queryAll(getInstance());
        if (accountList.size()>0){
            return accountList.get(0).getCoinWalletList();
        } else {
            return null;
        }

    }

    public static Account queryCurrrentAccount() {
        List<Account> accountList=AccountDaoOpe.queryAll(getInstance());
        if (accountList.size()>0){
            return accountList.get(0);
        } else {
            return null;
        }

    }

    public static String queryCurrrentAccountId() {
        List<Account> accountList=AccountDaoOpe.queryAll(getInstance());
        if (accountList.size()>0){
            return accountList.get(0).getAccountId();
        }else{
            return "";
        }

    }


    public static void queryIdAndDelete(String uuid) {
        AccountDaoOpe.queryId(getInstance(),uuid);
    }
}
